package com.alks.function.service.impl.produce;

import com.alks.common.aop.AutoPageAop;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.utils.UserInfoUtil;
import com.alks.common.utils.beanutils.ObjectUtils;
import com.alks.common.utils.stringUtils.ZStringUtils;
import com.alks.entity.data.entity.*;
import com.alks.entity.data.page.PageRecord;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.function.data.dto.chengKong.produce.PcLotDetailDto;
import com.alks.function.data.dto.produce.CutSeqDto;
import com.alks.function.data.request.chengKong.LotNoRequest;
import com.alks.function.data.request.chengKong.LotNoToStyleRequest;
import com.alks.function.mapper.chengKong.PcLotHeadMapper;
import com.alks.function.mapper.pcfactoryquery.FT_QR_PcCuttingLsPartMapper;
import com.alks.function.mapper.pcfactorywork.PcOutListPriceMapper;
import com.alks.function.mapper.produce.ComponentLabelMapper;
import com.alks.function.mapper.produce.CutPlanMapper;
import com.alks.function.mapper.produce.CutProcessChangeMapper;
import com.alks.function.mapper.stockdept.pcfactorystockquery.PcCuttingCollectDetailMapper;
import com.alks.function.mapper.stockdept.pcfactorystockquery.PcCuttingLsLabelMapper;
import com.alks.function.mapper.stockdept.pcfactorystockquery.PcLotPartProcessMapper;
import com.alks.function.mapper.stockdept.pcfactorystockquery.SD_SQ_PcLotPartMapper;
import com.alks.function.service.produce.CutProcessChangeService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CutProcessChangeServiceImpl implements CutProcessChangeService {

    @Autowired
    private CutProcessChangeMapper cutProcessChangeMapper;

    @Autowired
    private PcLotHeadMapper pcLotHeadMapper;

    @Autowired
    private PcOutListPriceMapper pcOutListPriceMapper;

    @Autowired
    private CutPlanMapper cutPlanMapper;

    @Autowired
    private PcLotPartProcessMapper pcLotPartProcessMapper;

    @Autowired
    private FT_QR_PcCuttingLsPartMapper pcCuttingLsPartMapper;

    @Autowired
    private SD_SQ_PcLotPartMapper pcLotPartMapper;

    @Autowired
    private PcCuttingLsLabelMapper pcCuttingLsLabelMapper;

    @Autowired
    private PcCuttingCollectDetailMapper pcCuttingCollectDetailMapper;

    @Autowired
    private ComponentLabelMapper componentLabelMapper;

    /**
     * 指令变更历史查询
     * @param request
     * @return
     */
    @Override
    @AutoPageAop
    public ResponseInfo searchList(LotNoToStyleRequest request) {
        String companyId = UserIdThread.get().getCompanyId();
        PageRecord<PcProcessChgHead> list = new PageRecord<>();
        List<PcProcessChgHead> headList = cutProcessChangeMapper.searchList(request, companyId);
        PageInfo t = new PageInfo(headList);
        list.setList(headList);
        list.setTotal(t.getTotal());
        return ResponseInfo.ok(list);
    }

    /**
     * 指令工艺变更资料查询
     * @param pcProcessChgHead
     * @return
     */
    @Override
    public ResponseInfo partList(PcProcessChgHead pcProcessChgHead) {
        return ResponseInfo.ok(cutProcessChangeMapper.selectByHead(pcProcessChgHead));
    }

    /**
     * 指令订单变更资料查询
     * @param pcProcessChgHead
     * @return
     */
    @Override
    public ResponseInfo qtyList(PcProcessChgHead pcProcessChgHead) {
        return ResponseInfo.ok(cutProcessChangeMapper.selectByHead2(pcProcessChgHead));
    }

    /**
     * 指令变更资料分析
     * @param request
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo analysis(LotNoRequest request) {
        if (ObjectUtils.isEmpty(request.getLotNo())){
            return ResponseInfo.error("指令不能为空!");
        }
        UserInfoUtil.UserInfo userInfo = UserInfoUtil.getUserInfo();
        LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PcLotHead::getLotNo,request.getLotNo()).eq(PcLotHead::getCompanyId,userInfo.getCompanyId());
        PcLotHead pcLotHead = pcLotHeadMapper.selectOne(wrapper);
        if (ObjectUtils.isEmpty(pcLotHead)){
            return ResponseInfo.error("指令不存在!");
        }
        if (!"Y".equals(pcLotHead.getCheckFlag())){
            return ResponseInfo.error("指令未审核!");
        }
        String cfmFlag = pcOutListPriceMapper.getSdStyleProcessHead(pcLotHead.getStyle(), pcLotHead.getColor(), userInfo.getCompanyId());
        if (ObjectUtils.isEmpty(cfmFlag)|| !"Y".equals(cfmFlag)){
            return ResponseInfo.error("配色工艺资料未建档或未检核!");
        }
        int labelCount = cutPlanMapper.selectPcCuttingLsLabel(userInfo.getCompanyId(), request.getLotNo());
        if (labelCount == 0) {
            return ResponseInfo.error("指令轮数标签未生成!");
        }
        cutProcessChangeMapper.delPcProcessChgHead(request.getLotNo(), userInfo.getCompanyId());
        cutProcessChangeMapper.delPcProcessChgPart(request.getLotNo(), userInfo.getCompanyId());
        cutProcessChangeMapper.delPcProcessChgQty(request.getLotNo(), userInfo.getCompanyId());
        cutProcessChangeMapper.addPcProcessChgQty(request.getLotNo(), userInfo.getCompanyId(), userInfo.getLoginName());
        cutProcessChangeMapper.addPcProcessChgQty2(request.getLotNo(), userInfo.getCompanyId(), userInfo.getLoginName());
        cutProcessChangeMapper.addPcProcessChgQty3(request.getLotNo(), userInfo.getCompanyId(), userInfo.getLoginName());
        cutProcessChangeMapper.updateProcessChgQty(request.getLotNo(), userInfo.getCompanyId());
        cutProcessChangeMapper.delProcessChgQtyEqualQty(request.getLotNo(), userInfo.getCompanyId());
        cutProcessChangeMapper.addPcProcessChgPart(request.getLotNo(), userInfo.getCompanyId(),userInfo.getLoginName(),pcLotHead.getStyle(),pcLotHead.getColor());
        cutProcessChangeMapper.addPcProcessChgPart2(request.getLotNo(), userInfo.getCompanyId(),userInfo.getLoginName(),pcLotHead.getStyle(),pcLotHead.getColor());

        //获取裁次变更数据
        List<SdStyleProcessNew> changeData = cutProcessChangeMapper.getChangeData(request.getLotNo(), userInfo.getCompanyId(), pcLotHead.getStyle(), pcLotHead.getColor());
        if (!ObjectUtils.isEmpty(changeData)){
            for (SdStyleProcessNew changeDatum : changeData) {
                //查询裁层数据
                Integer partNameCut = cutProcessChangeMapper.getPartNameCut(request.getLotNo(), userInfo.getCompanyId(), changeDatum.getPartName());
                if (ObjectUtils.isEmpty(partNameCut)){
                    partNameCut=0;
                }
                Integer cutSeq= changeDatum.getCutSeq()!=null?changeDatum.getCutSeq().intValue(): BigDecimal.ZERO.intValue();
                if (partNameCut!=cutSeq){
                    addPcProcessChgPart(request.getLotNo(), userInfo.getCompanyId(), userInfo.getLoginName(), changeDatum.getPartName(), changeDatum.getPartName(),"03.裁次变更");
                }

                //获取冲裁工序数量
                int punchingProcess = cutProcessChangeMapper.getPunchingProcess(userInfo.getCompanyId(), pcLotHead.getStyle(), pcLotHead.getColor(), changeDatum.getPartName());
                int punchingProcess2 = cutProcessChangeMapper.getPunchingProcess2(userInfo.getCompanyId(),request.getLotNo(), changeDatum.getPartName());
                if (punchingProcess!=punchingProcess2){
                    addPcProcessChgPart(request.getLotNo(), userInfo.getCompanyId(), userInfo.getLoginName(), changeDatum.getPartName(), changeDatum.getPartName(),"04.冲裁工序变更");
                }

                //获取工艺工序数量
                int processProcedure =cutProcessChangeMapper.getProcessProcedures(userInfo.getCompanyId(), pcLotHead.getStyle(), pcLotHead.getColor(), changeDatum.getPartName());
                int processProcedure2 =cutProcessChangeMapper.getProcessProcedures2(userInfo.getCompanyId(),request.getLotNo(), changeDatum.getPartName());
                if (processProcedure!=processProcedure2){
                    addPcProcessChgPart(request.getLotNo(), userInfo.getCompanyId(), userInfo.getLoginName(), changeDatum.getPartName(), changeDatum.getPartName(),"05.工艺工序变更");
                }

                //获取配套工艺工序数量
                int supportingProcess = cutProcessChangeMapper.getSupportingProcess(userInfo.getCompanyId(), pcLotHead.getStyle(), pcLotHead.getColor(), changeDatum.getPartName());
                int supportingProcess2 = cutProcessChangeMapper.getSupportingProcess2(userInfo.getCompanyId(),request.getLotNo(), changeDatum.getPartName());
                if (supportingProcess!=supportingProcess2){
                    addPcProcessChgPart(request.getLotNo(), userInfo.getCompanyId(), userInfo.getLoginName(), changeDatum.getPartName(), changeDatum.getPartName(),"06.配套工序变更");
                }
            }
        }

        //获取工艺变更数据数量
        int ChgQty = cutProcessChangeMapper.getPcProcessChgQty(userInfo.getCompanyId(), request.getLotNo());
        int ChgPart = cutProcessChangeMapper.getPcProcessChgPart(userInfo.getCompanyId(), request.getLotNo());
        if (ChgQty+ChgPart==0){
            return ResponseInfo.error("该指令无工艺变动!");
        }else {
            PcProcessChgHead head = new PcProcessChgHead();
            head.setCompanyId(userInfo.getCompanyId());
            head.setLotNo(request.getLotNo());
            head.setSysDate(LocalDate.now());
            head.setSysUser(userInfo.getUserName());
            head.setStyle(pcLotHead.getStyle());
            head.setColor(pcLotHead.getColor());
            cutProcessChangeMapper.addPcProcessChgHead(head);
        }
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 添加指令工艺变更资料
     * @param lotNo
     * @param companyId
     * @param loginName
     * @param oldPart
     * @param newPart
     * @param changeMemo
     */
    public void addPcProcessChgPart(String lotNo, String companyId, String loginName, String oldPart, String newPart, String changeMemo){
        PcProcessChgPart part = new PcProcessChgPart();
        part.setCompanyId(companyId);
        part.setLotNo(lotNo);
        part.setSysUser(loginName);
        part.setOldPart(oldPart);
        part.setSysDate(LocalDate.now());
        part.setNewPart(newPart);
        part.setChangeMemo(changeMemo);
        cutProcessChangeMapper.addPcProcessChgPart3(part);
    }

    /**
     * 修改数量
     * @param pcProcessChgPart
     * @return
     */
    @Override
    public ResponseInfo updatePart(PcProcessChgPart pcProcessChgPart) {
        PcProcessChgHead chgHead = cutProcessChangeMapper.selectPcProcessChgHead(pcProcessChgPart.getCompanyId(),pcProcessChgPart.getLotNo(), pcProcessChgPart.getSysDate());
        if (ObjectUtils.isEmpty(chgHead)){
            return ResponseInfo.error("变更指令不存在,请核实!");
        }
        if ("Y".equals(chgHead.getDealFlag())){
            return ResponseInfo.error("变更指令已处理,无法修改!");
        }
        cutProcessChangeMapper.updateBagQtyById(pcProcessChgPart);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 查询同配色指令
     * @param request
     * @return
     */
    @Override
    public ResponseInfo find(LotNoRequest request) {
        String companyId = UserIdThread.get().getCompanyId();
        LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PcLotHead::getCompanyId,companyId).eq(PcLotHead::getLotNo,request.getLotNo());
        PcLotHead pcLotHead = pcLotHeadMapper.selectOne(wrapper);
        if (ObjectUtils.isEmpty(pcLotHead)){
            return ResponseInfo.error("指令不存在,请核实!");
        }
        List<String> lotNos = pcLotHeadMapper.getOtherLotNoByHead(pcLotHead);
        if (ObjectUtils.isEmpty(lotNos)){
            return ResponseInfo.error("无同配色的其他指令资料!");
        }
        return ResponseInfo.ok(lotNos);
    }

    /**
     * 变更资料处理
     * @param request
     * @param override
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo deal(PcProcessChgHead request, boolean override) {
        String companyId = UserIdThread.get().getCompanyId();
        String loginName = UserIdThread.get().getLoginName();
        String userName = UserIdThread.get().getUserName();
        LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PcLotHead::getCompanyId, companyId).eq(PcLotHead::getLotNo, request.getLotNo());
        PcLotHead pcLotHead = pcLotHeadMapper.selectOne(wrapper);
        if (ObjectUtils.isEmpty(pcLotHead)) {
            return ResponseInfo.error("指令不存在,请核实!");
        }
        PcProcessChgHead chgHead = cutProcessChangeMapper.selectPcProcessChgHead(companyId, request.getLotNo(), request.getSysDate());
        if (ObjectUtils.isEmpty(chgHead)) {
            return ResponseInfo.error("该指令当日未进行变动资料分析!");
        }
        if ("Y".equals(chgHead.getDealFlag())){
            return ResponseInfo.error("该指令变动资料已处理!");
        }
        List<PcProcessChgPart> list = cutProcessChangeMapper.selectByHead(request);
        for (PcProcessChgPart cpcp : list) {
            if ("01.新增部位".equals(cpcp.getChangeMemo()) && (ZStringUtils.isNull(cpcp.getBagQty()) || cpcp.getBagQty().intValue() <= 0))
                return ResponseInfo.error("新增部位未设定每袋包装数量!");
            if ("02.取消部位".equals(cpcp.getChangeMemo()) && this.cutPlanMapper.countByLotNo(pcLotHead.getCompanyId(), pcLotHead.getLotNo()) > 0 && !override) {
                return ResponseInfo.warn("取消的部位已生产是否继续取消部位?");
            }
        }

        //工艺变更处理
        for (PcProcessChgPart chgPart : list) {
            if ("02.取消部位".equals(chgPart.getChangeMemo())) {
                CancelLocation(companyId, request.getLotNo(), chgPart.getOldPart());
            }
            if ("01.新增部位".equals(chgPart.getChangeMemo())){
                //生成指令工艺
                cutProcessChangeMapper.addPcLotPart(companyId,loginName,pcLotHead.getStyle(),pcLotHead.getColor(),chgPart.getNewPart(),request.getLotNo());
                addPcLotPart(request.getLotNo(), companyId, pcLotHead.getStyle(),pcLotHead.getColor(),chgPart.getNewPart());
                GenerateLabel(request.getLotNo(), companyId, pcLotHead, chgPart);
                GenerateProductionData(companyId,request.getLotNo(), chgPart.getNewPart());
            }
            if ("03.裁次变更".equals(chgPart.getChangeMemo())){
                int seqNo = cutProcessChangeMapper.getSdStyleProcessNewSeq(companyId, pcLotHead.getStyle(), pcLotHead.getColor(), chgPart.getNewPart());
                LambdaUpdateWrapper<PcLotPart> wrapper1 = new LambdaUpdateWrapper<PcLotPart>()
                        .eq(PcLotPart::getCompanyId, companyId).eq(PcLotPart::getLotNo, request.getLotNo()).eq(PcLotPart::getPartName, chgPart.getOldPart()).set(PcLotPart::getCutSeq, seqNo);
                pcLotPartMapper.update(null,wrapper1);
            }
            if ("04.冲裁工序变更".equals(chgPart.getChangeMemo())){
                ChangeOfPunchingProcess(request.getLotNo(), companyId, pcLotHead.getStyle(),pcLotHead.getColor(),chgPart.getNewPart());
            }
            if ("05.工艺工序变更".equals(chgPart.getChangeMemo())){
                ProcessChange(request.getLotNo(), companyId, pcLotHead.getStyle(),pcLotHead.getColor(),chgPart.getNewPart());
            }
            if ("06.配套工序变更".equals(chgPart.getChangeMemo())){
                ChangeOfSupportingProcess(request.getLotNo(), companyId, pcLotHead.getStyle(),pcLotHead.getColor(),chgPart.getNewPart());
            }
        }

        //数量变动处理
        int ChgQty = cutProcessChangeMapper.getPcProcessChgQty(companyId, request.getLotNo());
        if (ChgQty > 0){
            Backup(request.getLotNo(),companyId,userName,loginName);
            RegenerateTags(request.getLotNo(), companyId,pcLotHead.getStyle(),pcLotHead.getColor());
            GenerateProductionData2(companyId,request.getLotNo());
            Restore(request.getLotNo(), companyId);
        }
        cutProcessChangeMapper.updatePcProcessChgHead(companyId, request.getLotNo(), "Y");
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 还原数据
     * @param lotNo
     * @param companyId
     */
    private void Restore(String lotNo, String companyId) {
        int version = cutPlanMapper.getPcCuttingLsHeadBkToVersion(lotNo, companyId);
        if (version > 0){
            //还原PC_CUTTING_LS_PART_BK到PC_CUTTING_LS_PART(PROD_QTY)
            List<PcCuttingLsPart> bkList = pcCuttingLsPartMapper.getPcCuttingLsPartBkList(lotNo, version);
            List<PcCuttingLsPart> prodQtyList = pcCuttingLsPartMapper.getPcCuttingLsPartList(lotNo, companyId);
            for (PcCuttingLsPart rec : bkList) {
                Integer tempQty=rec.getProdQty();
                if (ZStringUtils.isNotEmpty(prodQtyList)){
                    Map<String, List<PcCuttingLsPart>> mapList = prodQtyList.stream()
                            .collect(Collectors.groupingBy(t -> t.getSizeNo() + "-" + t.getPartName() + "-" + t.getProcessCode()));
                    String key = ZStringUtils.format("{}-{}-{}", new Object[]{rec.getSizeNo(), rec.getPartName(), rec.getProcessCode()});
                    List<PcCuttingLsPart> values = mapList.get(key);
                    if (ZStringUtils.isNotEmpty(values)){
                        for (PcCuttingLsPart r : values) {
                            Integer lsQty = r.getLsQty() != null ? r.getLsQty() : 0;
                            Integer prodQty = r.getProdQty() != null ? r.getProdQty() : 0;
                            Integer qty=lsQty-prodQty;
                            if (qty<tempQty){
                                pcCuttingLsPartMapper.updatePcCuttingLsPartByProdQty(lotNo,companyId,rec.getSizeNo(),rec.getPartName(),rec.getProcessCode(),r.getLsNo().intValue(),qty);
                                tempQty=tempQty-qty;
                            }else {
                                pcCuttingLsPartMapper.updatePcCuttingLsPartByProdQty(lotNo,companyId,rec.getSizeNo(),rec.getPartName(),rec.getProcessCode(),r.getLsNo().intValue(),tempQty);
                            }
                        }
                    }
                }
            }

            //还原PC_CUTTING_LS_PART_BK到PC_CUTTING_LS_PART(SEND_QTY)
            List<PcCuttingLsPart> bkList2 = pcCuttingLsPartMapper.getPcCuttingLsPartBkList2(lotNo, version);
            List<PcCuttingLsPart> sendQtyList = pcCuttingLsPartMapper.getPcCuttingLsPartList2(lotNo, companyId);
            for (PcCuttingLsPart rec : bkList2) {
                Integer tempQty=rec.getSendQty();
                if (ZStringUtils.isNotEmpty(sendQtyList)){
                    Map<String, List<PcCuttingLsPart>> mapList = prodQtyList.stream()
                            .collect(Collectors.groupingBy(t -> t.getSizeNo() + "-" + t.getPartName() + "-" + t.getProcessCode()));
                    String key = ZStringUtils.format("{}-{}-{}", new Object[]{rec.getSizeNo(), rec.getPartName(), rec.getProcessCode()});
                    List<PcCuttingLsPart> values = mapList.get(key);
                    if (ZStringUtils.isNotEmpty(values)){
                        for (PcCuttingLsPart r : values) {
                            Integer prodQty = r.getProdQty() != null ? r.getProdQty() : 0;
                            Integer sendQty = r.getSendQty() != null ? r.getSendQty() : 0;
                            Integer qty=prodQty-sendQty;
                            if (qty<tempQty){
                                pcCuttingLsPartMapper.updatePcCuttingLsPartBySendQty(lotNo,companyId,rec.getSizeNo(),rec.getPartName(),rec.getProcessCode(),r.getLsNo().intValue(),qty);
                                tempQty=tempQty-qty;
                            }else {
                                pcCuttingLsPartMapper.updatePcCuttingLsPartBySendQty(lotNo,companyId,rec.getSizeNo(),rec.getPartName(),rec.getProcessCode(),r.getLsNo().intValue(),tempQty);
                            }
                        }
                    }
                }
            }

            //还原PC_CUT_PART_STATUS_BK到PC_CUT_PART_STATUS(PROD_QTY)
            List<PcCutPartStatus> statusBkList = cutPlanMapper.getPcCutPartStatusBkList(lotNo, version);
            List<PcCutPartStatus> prodQtyList2 = cutPlanMapper.getPcCutPartStatusList(lotNo, companyId);
            for (PcCutPartStatus rec : statusBkList) {
                Integer tempQty = rec.getProdQty() != null ? rec.getProdQty().intValue() : 0;
                if (ZStringUtils.isNotEmpty(prodQtyList2)) {
                    Map<String, List<PcCutPartStatus>> mapList = prodQtyList2.stream()
                            .collect(Collectors.groupingBy(t -> t.getSizeNo() + "-" + t.getPartName() + "-" + t.getProcessCode()));
                    String key = ZStringUtils.format("{}-{}-{}", new Object[]{rec.getSizeNo(), rec.getPartName(), rec.getProcessCode()});
                    List<PcCutPartStatus> values = mapList.get(key);
                    if (ZStringUtils.isNotEmpty(values)){
                        for (PcCutPartStatus r : values) {
                            Integer prodQty = r.getProdQty() != null ? r.getProdQty().intValue() : 0;
                            Integer ordQty = r.getOrdQty() != null ? r.getOrdQty().intValue() : 0;
                            BigDecimal lsNo = r.getLsNo() != null ? r.getLsNo() : BigDecimal.ZERO;
                            Integer qty=ordQty-prodQty;
                            if (qty<tempQty){
                                cutPlanMapper.updatePcCutPartStatusByProdQty(lotNo,companyId,rec.getSizeNo(),rec.getPartName(),rec.getProcessCode(),lsNo,qty);
                                tempQty=tempQty-qty;
                            }else {
                                cutPlanMapper.updatePcCutPartStatusByProdQty(lotNo,companyId,rec.getSizeNo(),rec.getPartName(),rec.getProcessCode(),lsNo,tempQty);
                            }
                        }
                    }
                }
            }

            //还原PC_CUT_PART_STATUS_BK到PC_CUT_PART_STATUS(SEND_QTY)
            List<PcCutPartStatus> statusBkList2 = cutPlanMapper.getPcCutPartStatusBkList2(lotNo, version);
            List<PcCutPartStatus> sendQtyList2 = cutPlanMapper.getPcCutPartStatusList2(lotNo, companyId);
            for (PcCutPartStatus rec : statusBkList2) {
                Integer tempQty = rec.getProdQty() != null ? rec.getProdQty().intValue() : 0;
                if (ZStringUtils.isNotEmpty(sendQtyList2)) {
                    Map<String, List<PcCutPartStatus>> mapList = sendQtyList2.stream()
                            .collect(Collectors.groupingBy(t -> t.getSizeNo() + "-" + t.getPartName() + "-" + t.getProcessCode()));
                    String key = ZStringUtils.format("{}-{}-{}", new Object[]{rec.getSizeNo(), rec.getPartName(), rec.getProcessCode()});
                    List<PcCutPartStatus> values = mapList.get(key);
                    if (ZStringUtils.isNotEmpty(values)){
                        for (PcCutPartStatus r : values) {
                            Integer prodQty = r.getProdQty() != null ? r.getProdQty().intValue() : 0;
                            Integer sendQty = r.getSendQty() != null ? r.getSendQty().intValue() : 0;
                            Integer lsNo = r.getLsNo() != null ? r.getLsNo().intValue() : 0;
                            Integer qty=prodQty-sendQty;
                            if (qty<tempQty){
                                cutPlanMapper.updatePcCutPartStatusBySendQty(lotNo,companyId,rec.getSizeNo(),rec.getPartName(),rec.getProcessCode(),lsNo,qty);
                                tempQty=tempQty-qty;
                            }else {
                                cutPlanMapper.updatePcCutPartStatusBySendQty(lotNo,companyId,rec.getSizeNo(),rec.getPartName(),rec.getProcessCode(),lsNo,tempQty);
                            }
                        }
                    }
                }
            }

            //还原PC_STITCH_PART_STATUS_BK到PC_STITCH_PART_STATUS(PROD_QTY)
            List<PcStitchPartStatus> statusBkList3 = cutPlanMapper.getPcStitchPartStatusBkList(lotNo, version);
            List<PcStitchPartStatus> prodQtyList3 = cutPlanMapper.getPcStitchPartStatusList(lotNo, companyId);
            for (PcStitchPartStatus rec : statusBkList3) {
                Integer tempQty = rec.getProdQty() != null ? rec.getProdQty().intValue() : 0;
                if (ZStringUtils.isNotEmpty(prodQtyList3)) {
                    Map<String, List<PcStitchPartStatus>> mapList = prodQtyList3.stream()
                            .collect(Collectors.groupingBy(t -> t.getSizeNo() + "-" + t.getPartName()));
                    String key = ZStringUtils.format("{}-{}-{}", new Object[]{rec.getSizeNo(), rec.getPartName()});
                    List<PcStitchPartStatus> values = mapList.get(key);
                    if (ZStringUtils.isNotEmpty(values)){
                        for (PcStitchPartStatus r : values) {
                            Integer prodQty = r.getProdQty() != null ? r.getProdQty().intValue() : 0;
                            Integer ordQty = r.getOrdQty() != null ? r.getOrdQty().intValue() : 0;
                            Integer qty=ordQty-prodQty;
                            if (qty<tempQty){
                                cutPlanMapper.updatePcStitchPartStatusByProdQty(lotNo,companyId,rec.getSizeNo(),rec.getPartName(),qty);
                                tempQty=tempQty-qty;
                            }else {
                                cutPlanMapper.updatePcStitchPartStatusByProdQty(lotNo,companyId,rec.getSizeNo(),rec.getPartName(),tempQty);
                            }
                        }
                    }
                }
            }

            //还原PC_STITCH_PART_STATUS_BK到PC_STITCH_PART_STATUS(SEND_QTY)
            List<PcStitchPartStatus> statusBkList4 = cutPlanMapper.getPcStitchPartStatusBkList2(lotNo, version);
            List<PcStitchPartStatus> sendQtyList4 = cutPlanMapper.getPcStitchPartStatusList2(lotNo, companyId);
            for (PcStitchPartStatus rec : statusBkList4) {
                Integer tempQty = rec.getProdQty() != null ? rec.getProdQty().intValue() : 0;
                if (ZStringUtils.isNotEmpty(sendQtyList4)) {
                    Map<String, List<PcStitchPartStatus>> mapList = sendQtyList4.stream()
                            .collect(Collectors.groupingBy(t -> t.getSizeNo() + "-" + t.getPartName()));
                    String key = ZStringUtils.format("{}-{}-{}", new Object[]{rec.getSizeNo(), rec.getPartName()});
                    List<PcStitchPartStatus> values = mapList.get(key);
                    if (ZStringUtils.isNotEmpty(values)){
                        for (PcStitchPartStatus r : values) {
                            Integer prodQty = r.getProdQty() != null ? r.getProdQty().intValue() : 0;
                            Integer sendQty = r.getSendQty() != null ? r.getSendQty().intValue() : 0;
                            Integer qty=prodQty-sendQty;
                            if (qty<tempQty){
                                cutPlanMapper.updatePcStitchPartStatusBySendQty(lotNo,companyId,rec.getSizeNo(),rec.getPartName(),qty);
                                tempQty=tempQty-qty;
                            }else {
                                cutPlanMapper.updatePcStitchPartStatusBySendQty(lotNo,companyId,rec.getSizeNo(),rec.getPartName(),tempQty);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 生成工序发料状态数据
     * @param companyId
     * @param lotNo
     */
    private void GenerateProductionData2(String companyId, String lotNo){
        //生成 PC_CUTTING_LS_PART/PC_CUT_PART_STATUS/PC_STITCH_PART_STATUS
        pcCuttingLsPartMapper.addPcCuttingLsPart3(companyId, lotNo);
        cutPlanMapper.addPcCutPartStatus3(companyId, lotNo);
        cutPlanMapper.addPcStitchPartStatus4(companyId, lotNo);
    }

    /**
     * 重新生成标签
     * @param lotNo
     * @param companyId
     * @param style
     * @param color
     */
    private void RegenerateTags(String lotNo, String companyId,String style, String color) {
        List<CutSeqDto> partList = cutProcessChangeMapper.getPcLotPartList(lotNo, companyId);
        for (CutSeqDto recp : partList) {
            Integer bagQty = componentLabelMapper.getPcLotCutPartBag(lotNo, companyId, recp.getPartName());
            List<PcCuttingLsDetail> details = cutPlanMapper.getPcCuttingLsDetails(lotNo, companyId);
            if (!ObjectUtils.isEmpty(bagQty)){
                for (PcCuttingLsDetail rec2 : details) {
                    Integer qty = rec2.getQty();
                    int t;
                    int curIndex = 1;
                    if (qty> bagQty){
                        t = (int)Math.ceil(Double.valueOf((double)qty) / (double)bagQty);
                    }else {
                        t = 1;
                    }
                    while (qty>0){
                        String sizeNum = rec2.getSizeNo().replaceAll("\\D", "");
                        if (sizeNum.length() == 0) {
                            sizeNum = "0";
                        }
                        String sizeNo = String.format("%03d", Integer.parseInt(sizeNum));
                        String label = String.format("%s%02d%s%02d%d", lotNo,recp.getSeqNo(), sizeNo, rec2.getLsNo(), curIndex);
                        String batchCode = String.format("%d-%d", t, curIndex);
                        if (qty> bagQty){
                            cutPlanMapper.addPcCuttingLsDetail2(label,rec2.getLotNo(),recp.getPartName(),curIndex,batchCode, bagQty,style, color,rec2.getLsNo(),rec2.getSizeNo());
                            qty=qty- bagQty;
                        }else {
                            if (qty>0) {
                                cutPlanMapper.addPcCuttingLsDetail2(label,rec2.getLotNo(), recp.getPartName(),curIndex,batchCode,qty,style, color,rec2.getLsNo(),rec2.getSizeNo());
                            }
                            qty=0;
                        }
                        curIndex=curIndex+1;
                    }
                }
            }else {
                for (PcCuttingLsDetail rec : details) {
                    String sizeNum = rec.getSizeNo().replaceAll("\\D", "");
                    if (sizeNum.length() == 0) {
                        sizeNum = "0";
                    }
                    String sizeNo = String.format("%03d", Integer.parseInt(sizeNum));
                    String label = String.format("%s%02d%s%02d%d", lotNo,recp.getSeqNo(), sizeNo, rec.getLsNo(), 1);
                    cutPlanMapper.addPcCuttingLsDetail3(label,rec.getLotNo(), recp.getPartName(),1,"1-1",style, color,rec.getLsNo(),rec.getSizeNo());
                }
            }
        }
        cutPlanMapper.updatePcCuttingLsDetailToBk(companyId,lotNo);
    }

    /**
     * 备份数据
     * @param lotNo
     * @param companyId
     * @param userName
     */
    private void Backup(String lotNo, String companyId, String userName, String loginName) {
        int version = cutPlanMapper.getPcCuttingLsHeadBkToVersion(lotNo, companyId);
        version=version+1;
        pcCuttingLsLabelMapper.delPcCuttingLsLabelTemp();
        pcCuttingLsLabelMapper.addPcCuttingLsLabelTemp(lotNo, companyId);
        pcCuttingLsLabelMapper.addPcCuttingLsLabelTemp2(lotNo, companyId);

        //备份数据
        cutPlanMapper.addPcCuttingLsHeadBk(lotNo, companyId, userName, version);
        cutPlanMapper.addPcCuttingLsDetailBk(lotNo, companyId, userName, version);

        cutPlanMapper.addPcLastLsHeadBk(lotNo, companyId, userName, version);
        cutPlanMapper.addPcLastLsDetailBk(lotNo, companyId, userName, version);

        cutPlanMapper.addPcCuttingLsLabelBk(lotNo, companyId, userName, version);
        pcCuttingCollectDetailMapper.addPcCuttingCollectDetailBk(lotNo, userName, version);

        pcCuttingLsPartMapper.addPcCuttingLsPartBk(lotNo, userName, version);
        cutPlanMapper.addPcCutPartStatusBk(lotNo, userName, version);
        cutPlanMapper.addPcStitchPartStatusBk(lotNo, userName, version);

        //删除原数据
        cutPlanMapper.deleteByLotNoToPcCuttingLsDetail(companyId, lotNo);
        cutPlanMapper.deleteByLotNoToPcCuttingLsHead(companyId, lotNo);
        cutPlanMapper.delPcLastLsDetail(companyId, lotNo);
        cutPlanMapper.delPcLastLsHead(companyId, lotNo);
        LambdaQueryWrapper<PcCuttingLsLabel> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PcCuttingLsLabel::getLotNo, lotNo).eq(PcCuttingLsLabel::getCompanyId, companyId);
        pcCuttingLsLabelMapper.delete(lambdaQueryWrapper);
        LambdaQueryWrapper<PcCuttingLsPart> lsPartLambdaQueryWrapper = new LambdaQueryWrapper<>();
        lsPartLambdaQueryWrapper.eq(PcCuttingLsPart::getLotNo, lotNo).eq(PcCuttingLsPart::getCompanyId, companyId);
        pcCuttingLsPartMapper.delete(lsPartLambdaQueryWrapper);
        cutPlanMapper.delPcCutPartStatus(companyId, lotNo);
        componentLabelMapper.delPcStitchPartStatus(companyId, lotNo);

        cutPlanMapper.addPcCuttingLsHeadToTemp(lotNo, version);
        cutPlanMapper.addPcCuttingLsDetailToTemp(lotNo, version);
        int lsNo = cutPlanMapper.getPcCuttingLsHeadToLsNo(lotNo);
        lsNo = lsNo + 1;

        PcCuttingLsHead cuttingLsHead = new PcCuttingLsHead();
        cuttingLsHead.setCompanyId(companyId);
        cuttingLsHead.setLotNo(lotNo);
        cuttingLsHead.setLsNo(lsNo);
        cuttingLsHead.setQty(0);
        cuttingLsHead.setUserId(loginName);
        cuttingLsHead.setSysDate(LocalDateTime.now());
        cutPlanMapper.addPcCuttingLsHead(cuttingLsHead);

        List<PcLotDetailDto> numberDetails = pcLotHeadMapper.getCodeDetails(lotNo, companyId);
        for (PcLotDetailDto rec : numberDetails) {
            Integer qty = cutPlanMapper.getPcCuttingLsHeadToQty(lotNo, rec.getSizeNo());
            if (qty==null){
                qty = 0;
            }
            int OrdQty = rec.getTotalQty().intValue();
            if (OrdQty > qty) {
                PcCuttingLsDetail cuttingLsDetail = new PcCuttingLsDetail();
                cuttingLsDetail.setCompanyId(companyId);
                cuttingLsDetail.setLotNo(lotNo);
                cuttingLsDetail.setLsNo(lsNo);
                cuttingLsDetail.setSizeSeq(BigDecimal.valueOf(Long.parseLong(rec.getSeqNo())));
                cuttingLsDetail.setSizeNo(rec.getSizeNo());
                cuttingLsDetail.setQty(OrdQty - qty);
                cutPlanMapper.addPcCuttingLsDetail(cuttingLsDetail);
            } else {
                PcCuttingLsDetail cuttingLsDetail = new PcCuttingLsDetail();
                cuttingLsDetail.setCompanyId(companyId);
                cuttingLsDetail.setLotNo(lotNo);
                cuttingLsDetail.setLsNo(lsNo);
                cuttingLsDetail.setSizeSeq(BigDecimal.valueOf(Long.parseLong(rec.getSeqNo())));
                cuttingLsDetail.setSizeNo(rec.getSizeNo());
                cuttingLsDetail.setQty(0);
                cutPlanMapper.addPcCuttingLsDetail(cuttingLsDetail);
            }
        }
        cutPlanMapper.updatePcCuttingLsHeadToQty(lotNo, lsNo);
    }

    /**
     * 配套工序变更
     * @param lotNo
     * @param companyId
     * @param style
     * @param color
     * @param partName
     */
    private void ChangeOfSupportingProcess(String lotNo, String companyId, String style, String color, String partName){
        int cnt1 = cutProcessChangeMapper.getSupportingProcess(companyId,style, color, partName);
        int cnt2 = cutProcessChangeMapper.getSupportingProcess2(companyId,lotNo, partName);
        if (cnt1>0 && cnt2==0){
            pcCuttingLsPartMapper.addPcCuttingLsPart2(companyId, lotNo,partName,"03");
            cutPlanMapper.addPcCutPartStatus2(companyId,lotNo, partName,"03");
            cutPlanMapper.addPcStitchPartStatus3(companyId,lotNo, partName);
            PcLotPartProcess lotPartProcess = getPcLotPartProcess(companyId, lotNo, partName, "03");
            pcLotPartProcessMapper.insert(lotPartProcess);
        }
        if (cnt1==0 && cnt2>0){
            cutProcessChangeMapper.delPcStitchPartStatus(companyId,lotNo,partName);
            cutProcessChangeMapper.delPcCutPartStatus2(companyId,lotNo,partName,"03");
            cutProcessChangeMapper.delPcCuttingLsPart2(companyId,lotNo,partName,"03");
            cutProcessChangeMapper.delPcLotPartProcess2(companyId,lotNo,partName,"03");
        }
    }

    /**
     * 工艺工序变更
     * @param lotNo
     * @param companyId
     * @param style
     * @param color
     * @param partName
     */
    private void ProcessChange(String lotNo, String companyId, String style, String color, String partName){
        int cnt1 =cutProcessChangeMapper.getProcessProcedures(companyId,style, color, partName);
        int cnt2 =cutProcessChangeMapper.getProcessProcedures2(companyId,lotNo, partName);
        if (cnt1>0 && cnt2==0){
            pcCuttingLsPartMapper.addPcCuttingLsPart2(companyId, lotNo,partName,"02");
            cutPlanMapper.addPcCutPartStatus2(companyId,lotNo, partName,"02");
            PcLotPartProcess lotPartProcess = getPcLotPartProcess(companyId, lotNo, partName, "02");
            pcLotPartProcessMapper.insert(lotPartProcess);
        }
        if (cnt1==0 && cnt2>0){
            cutProcessChangeMapper.delPcStitchPartStatus(companyId,lotNo,partName);
            cutProcessChangeMapper.delPcCutPartStatus2(companyId,lotNo,partName,"02");
            cutProcessChangeMapper.delPcCuttingLsPart2(companyId,lotNo,partName,"02");
            cutProcessChangeMapper.delPcLotPartProcess2(companyId,lotNo,partName,"02");
        }
    }

    /**
     * 冲裁工序变更
     * @param lotNo
     * @param companyId
     * @param style
     * @param color
     * @param partName
     */
    private void ChangeOfPunchingProcess(String lotNo, String companyId, String style, String color, String partName) {
        int cnt1 = cutProcessChangeMapper.getPunchingProcess(companyId, style, color, partName);
        int cnt2 = cutProcessChangeMapper.getPunchingProcess2(companyId, lotNo, partName);
        //新增工序
        if (cnt1>0 && cnt2==0){
            pcCuttingLsPartMapper.addPcCuttingLsPart2(companyId, lotNo,partName,"01");
            cutPlanMapper.addPcCutPartStatus2(companyId,lotNo, partName,"01");
            PcLotPartProcess lotPartProcess = getPcLotPartProcess(companyId, lotNo, partName, "01");
            pcLotPartProcessMapper.insert(lotPartProcess);
        }
        //取消工序
        if (cnt1==0 && cnt2>0){
            cutProcessChangeMapper.delPcCutPartStatus2(companyId,lotNo,partName,"01");
            cutProcessChangeMapper.delPcCuttingLsPart2(companyId,lotNo,partName,"01");
            cutProcessChangeMapper.delPcLotPartProcess2(companyId,lotNo,partName,"01");
        }
    }

    /**
     * 生成工序发料状态数据
     * @param companyId
     * @param lotNo
     * @param partName
     */
    private void GenerateProductionData(String companyId, String lotNo, String partName){
        pcCuttingLsPartMapper.addPcCuttingLsPart(companyId, lotNo, partName);
        cutPlanMapper.addPcCutPartStatus(companyId, lotNo, partName);
        cutPlanMapper.addPcStitchPartStatus2(companyId, lotNo, partName);
    }

    /**
     * 生成标签
     * @param lotNo
     * @param companyId
     * @param pcLotHead
     * @param chgPart
     */
    private void GenerateLabel(String lotNo, String companyId, PcLotHead pcLotHead, PcProcessChgPart chgPart) {
        int seqNo = cutProcessChangeMapper.getSdStyleProcessNewSeq(companyId, pcLotHead.getStyle(), pcLotHead.getColor(), chgPart.getNewPart());
        List<PcCuttingLsDetail> details = cutPlanMapper.getPcCuttingLsDetails(lotNo, companyId);
        for (PcCuttingLsDetail rec2 : details) {
            Integer qty = rec2.getQty();
            int t;
            int curIndex = 1;
            if (qty> chgPart.getBagQty()){
                t = (int)Math.ceil(Double.valueOf((double)qty) / (double) chgPart.getBagQty());
            }else {
                t = 1;
            }
            while (qty>0){
                String sizeNum = rec2.getSizeNo().replaceAll("\\D", "");
                if (sizeNum.length() == 0) {
                    sizeNum = "0";
                }
                String sizeNo = String.format("%03d", Integer.parseInt(sizeNum));
                String label = String.format("%s%02d%s%02d%d", lotNo,seqNo, sizeNo, rec2.getLsNo(), curIndex);
                String batchCode = String.format("%d-%d", t, curIndex);
                if (qty> chgPart.getBagQty()){
                    cutPlanMapper.addPcCuttingLsDetail2(label,rec2.getLotNo(), chgPart.getNewPart(),curIndex,batchCode, chgPart.getBagQty(), pcLotHead.getStyle(), pcLotHead.getColor(),rec2.getLsNo(),rec2.getSizeNo());
                    qty=qty- chgPart.getBagQty();
                }else {
                    cutPlanMapper.addPcCuttingLsDetail2(label,rec2.getLotNo(), chgPart.getNewPart(),curIndex,batchCode,qty, pcLotHead.getStyle(), pcLotHead.getColor(),rec2.getLsNo(),rec2.getSizeNo());
                    qty=0;
                }
                curIndex=curIndex+1;
            }
        }
    }

    private void addPcLotPart(String lotNo, String companyId, String style, String color, String partName) {
        int punchingProcess = cutProcessChangeMapper.getPunchingProcess(companyId, style, color, partName);
        if (punchingProcess > 0){
            PcLotPartProcess lotPartProcess = getPcLotPartProcess(companyId, lotNo, partName, "01");
            pcLotPartProcessMapper.insert(lotPartProcess);
        }

        int processProcedure =cutProcessChangeMapper.getProcessProcedures(companyId, style, color, partName);
        if (processProcedure > 0){
            PcLotPartProcess lotPartProcess = getPcLotPartProcess(companyId, lotNo, partName, "02");
            pcLotPartProcessMapper.insert(lotPartProcess);
        }

        int supportingProcess = cutProcessChangeMapper.getSupportingProcess(companyId, style,color, partName);
        if (supportingProcess >0){
            PcLotPartProcess lotPartProcess = getPcLotPartProcess(companyId, lotNo, partName, "03");
            pcLotPartProcessMapper.insert(lotPartProcess);
        }
    }

    @NotNull
    private PcLotPartProcess getPcLotPartProcess(String companyId, String lotNo, String partName, String seqNo) {
        PcLotPartProcess lotPartProcess = new PcLotPartProcess();
        lotPartProcess.setCompanyId(companyId);
        lotPartProcess.setLotNo(lotNo);
        lotPartProcess.setPartName(partName);
        lotPartProcess.setSeqNo(seqNo);
        lotPartProcess.setProcessCode(seqNo);
        return lotPartProcess;
    }

    /**
     * 取消部位
     * @param companyId
     * @param lotNo
     * @param partName
     */
    public void CancelLocation(String companyId, String lotNo,String partName){
        cutProcessChangeMapper.delPcStitchPartStatus(companyId,lotNo,partName);
        cutProcessChangeMapper.delPcCutPartStatus(companyId,lotNo,partName);
        cutProcessChangeMapper.delPcCuttingLsPart(companyId,lotNo,partName);
        cutProcessChangeMapper.delPcCuttingLsLabel(companyId,lotNo,partName);
        cutProcessChangeMapper.delPcLotPartProcess(companyId,lotNo,partName);
        cutProcessChangeMapper.delPcLotPart(companyId,lotNo,partName);
    }

    /**
     * 指令列表
     * @param request
     * @return
     */
    @Override
    @AutoPageAop
    public ResponseInfo getLotNoList(LotNoToStyleRequest request) {
        String companyId = UserIdThread.get().getCompanyId();
        List<String> lotNoList = pcLotHeadMapper.getLotNoList(companyId, request.getLotNo());
        PageRecord<String> list = new PageRecord<>();
        list.setList(lotNoList);
        PageInfo t = new PageInfo(lotNoList);
        list.setTotal(t.getTotal());
        return ResponseInfo.ok(list);
    }
}
